/*
 * BankAccount.java
 *
 *  
 */
package org.msb.finance.data;

import java.math.BigDecimal;

import org.msb.finance.res.CoreMessages;

/**
 * The {@code BankAccount} class represents bank accounts. A bank account, in this system, is an account in which cash
 * transactions occur. In addition the {@code BankAccount} class has a few additional features over the {@code Account}
 * class:
 * <ul>
 * <li>it tracks a minimum desired balance; and</li>
 * <li>it tracks any associated overdraft protection.</li>
 * </ul>
 * 
 * @author Marc Boudreau
 * 
 */
public class BankAccount extends Account {

	/*
	 * The minimum desired balance. This value can be set to trigger an alarm if the application can forecast that the
	 * balance will fall below this value. This is useful for accounts that waive banking fees if the balance remains
	 * above a certain amount.
	 */
	private BigDecimal minDesiredBalance;

	/*
	 * 
	 */
	private BigDecimal overdraftLimit;

	/*
	 * This constructor is required by the JDO specification.
	 */
	@SuppressWarnings("unused")
	private BankAccount() {
		this(null);
	}

	/**
	 * Constructs a new {@code BankAccount} instance with the given name.
	 * 
	 * @param name
	 *            A {@link String} object containing the name to set for the new account.
	 */
	public BankAccount(String name) {
		super(name);

		minDesiredBalance = new BigDecimal(0);
		overdraftLimit = new BigDecimal(0);
	}

	/**
	 * Returns the minimum desired balance for this account. The minimum desired balance is simply a threshold used by
	 * planning applications to alert the user that the account balance has dropped below or may drop below this
	 * threshold.
	 * 
	 * @return A {@link BigDecimal} object containing the minimum desired balance.
	 */
	public BigDecimal getMinimumDesiredBalance() {
		return minDesiredBalance;
	}

	/**
	 * Sets the minimum desired balance for this account to the value of the provided {@link BigDecimal} object.
	 * 
	 * @param balance
	 *            A {@link BigDecimal} object containing the minimum balance.
	 */
	public void setMinimumDesirableBalance(BigDecimal balance) {
		if (null == balance) {
			throw new NullPointerException();
		}

		this.minDesiredBalance = balance;
	}

	/**
	 * Returns the overdraft protection limit for this account. This amount is a positive amount, but corresponds to how
	 * much of a negative balance the account is allowed to attain before debit transactions are rejected. For example,
	 * an overdraft limit of {@code 500} means that the account balance is permitted to reach as low as {@code -500}.
	 * The system maintains this value for reference purposes only, it will not reject transactions that would violate
	 * this limit.
	 * 
	 * @return A {@link BigDecimal} object that contains the limit amount.
	 */
	public BigDecimal getOverdraftLimit() {
		return overdraftLimit;
	}

	/**
	 * Sets the overdraft protection amount to the provided value in the {@code limit} parameter. This parameter cannot
	 * be {@code null} and it cannot represent a negative number.
	 * 
	 * @param limit
	 * 
	 * @throws NullPointerException
	 *             Thrown if the {@code limit} parameter is {@code null}.
	 * @throws IllegalArgumentException
	 *             Thrown if the {@code limit} parameter represents a negative number.
	 */
	public void setOverdraftLimit(BigDecimal limit) {
		if (-1 == limit.signum()) {
			throw new IllegalArgumentException(CoreMessages
					.getString("org.msb.finance.data.BankAccount.setOverdraftLimitNegativeValue")); //$NON-NLS-1$
		}

		overdraftLimit = limit;
	}
}
